home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Dr. Windows 3
/
dr win3.zip
/
dr win3
/
PROGRAMR
/
OLE2BOOK.ZIP
/
CHAP12.ZIP
/
PATRON
/
TENANT.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-19
|
41KB
|
1,665 lines
/*
* TENANT.CPP
* Modifications for Chapter 12
*
* Implementation of the CTentant class which holds information
* for a single object on a page. It maintains position, references
* to data, and a storage.
*
* Copyright (c)1993 Microsoft Corporation, All Rights Reserved
*
* Kraig Brockschmidt, Software Design Engineer
* Microsoft Systems Developer Relations
*
* Internet : kraigb@microsoft.com
* Compuserve: >INTERNET:kraigb@microsoft.com
*/
#include "patron.h"
/*
* CTenant::CTenant
* CTenant::~CTenant
*
* Constructor Parameters:
* dwID DWORD identifier for this page.
* hWnd HWND of the pages window.
* pPG LPCPages to the parent structure.
*/
CTenant::CTenant(DWORD dwID, HWND hWnd, LPCPages pPG)
{
m_hWnd=hWnd;
m_dwID=dwID;
m_fInitialized=0;
m_pIStorage=NULL;
m_cOpens=0;
m_pObj=NULL;
m_pPG =pPG;
m_cRef=0;
m_pIOleObject=NULL;
m_pIViewObject=NULL;
m_pIOleClientSite=NULL;
m_pIAdviseSink=NULL;
//CHAPTER12MOD
m_pmkFile=NULL;
m_fLinkAvail=TRUE; //Checked on FLoad.
//End CHAPTER12MOD
return;
}
CTenant::~CTenant(void)
{
//CHAPTER12MOD
if (NULL!=m_pmkFile)
m_pmkFile->Release();
//End CHAPTER12MOD
if (NULL!=m_pIViewObject)
{
m_pIViewObject->SetAdvise(m_fe.dwAspect, 0, NULL);
m_pIViewObject->Release();
}
if (NULL!=m_pIOleObject)
m_pIOleObject->Release();
//We delete our own interfaces since we control them
if (NULL!=m_pIAdviseSink)
delete m_pIAdviseSink;
if (NULL!=m_pIOleClientSite)
delete m_pIOleClientSite;
if (NULL!=m_pObj)
{
//We know we only hold one reference from UCreate or FLoad
m_pObj->Release();
m_pObj=NULL;
}
return;
}
/*
* CTenant::QueryInterface
* CTenant::AddRef
* CTenant::Release
*
* Purpose:
* IUnknown members for CTenant object.
*/
STDMETHODIMP CTenant::QueryInterface(REFIID riid, LPLPVOID ppv)
{
*ppv=NULL;
if (IsEqualIID(riid, IID_IUnknown))
*ppv=(LPVOID)this;
if (IsEqualIID(riid, IID_IOleClientSite))
*ppv=(LPVOID)m_pIOleClientSite;
if (IsEqualIID(riid, IID_IAdviseSink))
*ppv=(LPVOID)m_pIAdviseSink;
if (NULL!=*ppv)
{
((LPUNKNOWN)*ppv)->AddRef();
return NOERROR;
}
return ResultFromScode(E_NOINTERFACE);
}
STDMETHODIMP_(ULONG) CTenant::AddRef(void)
{
return ++m_cRef;
}
STDMETHODIMP_(ULONG) CTenant::Release(void)
{
ULONG cRefT;
cRefT=--m_cRef;
if (0L==m_cRef)
delete this;
return cRefT;
}
/*
* CTenant::GetID
*
* Return Value:
* DWORD dwID field in this tenant. This function is only here
* to avoid hiding inline implementations in pages.h
*/
DWORD CTenant::GetID(void)
{
return m_dwID;
}
/*
* CTenant::GetStorageName
*
* Parameters:
* pszName LPSTR to a buffer in which to store the storage name
* for this tenant.
*
* Return Value:
* UINT Number of characters stored.
*/
UINT CTenant::GetStorageName(LPSTR pszName)
{
return wsprintf(pszName, "Tenant %lu", m_dwID);
}
/*
* CTenant::UCreate
*
* Purpose:
* Creates a new tenant of the given CLSID, which can be either a
* static bitmap or metafile now (Chapter 7) and which may eventually
* be any OLE object.
*
* Parameters:
* tType TENANTTYPE to create, either a static metafile, bitmap,
* or some kind of OLE object (later chapters)
* This determined which OleCreate* call we use.
* pvType LPVOID providing the relevant pointer from which
* to create the tenant, depending on iType.
* pFE LPFORMATETC specifying the type of renderings to use.
* pptl LPPOINTL in which we can store offset coordinates.
* pszl LPSIZEL where this object should store its lometric extents.
* pIStorage LPSTORAGE of the page we live in. We have to
* create another storage under this for the tenant.
* ppo LPPATRONOBJECT containing placement data.
* dwData DWORD containing extra data, sensitive to iType.
*
* Return Value:
* UINT A UCREATE_* value depending on what we actually do.
*/
UINT CTenant::UCreate(TENANTTYPE tType, LPVOID pvType, LPFORMATETC pFE
, LPPOINTL pptl, LPSIZEL pszl, LPSTORAGE pIStorage
, LPPATRONOBJECT ppo, DWORD dwData)
{
HRESULT hr;
LPUNKNOWN pObj;
UINT uRet=UCREATE_GRAPHICONLY;
if (NULL==pvType || NULL==pIStorage)
return UCREATE_FAILED;
//Fail if this is called for an already living tenant.
if (m_fInitialized)
return UCREATE_FAILED;
m_fInitialized=TRUE;
//Create a new storage for this tenant.
if (!FOpen(pIStorage))
return UCREATE_FAILED;
/*
* Get the placement info if it's here. We either have a non-NULL
* LPPATRONOBJECT in ppo or we have to use default placement and
* retrieve the size from the object itself.
*/
pszl->cx=0;
pszl->cy=0;
if (NULL!=ppo)
{
*pFE=ppo->fe;
*pptl=ppo->ptl;
*pszl=ppo->szl; //Could be 0,0 in which case we ask object
uRet=UCREATE_PLACEDOBJECT;
}
hr=ResultFromScode(E_FAIL);
//Now create an object based specifically for the type.
switch (tType)
{
case TENANTTYPE_NULL:
break;
case TENANTTYPE_STATIC:
/*
* We could use OleCreateStaticFromData here which does
* pretty much what we're doing below. However, it does
* not allow us to control whether we paste a bitmap or
* a metafile--it uses metafile first, bitmap second. For
* this reason we'll use code developed in Chapter 6's
* FreeLoader to affect the paste.
*/
hr=CreateStatic((LPDATAOBJECT)pvType, pFE, &pObj);
break;
case TENANTTYPE_EMBEDDEDOBJECT:
hr=OleCreate(*((LPCLSID)pvType), IID_IUnknown, OLERENDER_DRAW
, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
break;
case TENANTTYPE_EMBEDDEDFILE:
hr=OleCreateFromFile(CLSID_NULL, (LPSTR)pvType, IID_IUnknown
, OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
break;
case TENANTTYPE_EMBEDDEDOBJECTFROMDATA:
hr=OleCreateFromData((LPDATAOBJECT)pvType, IID_IUnknown
, OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
break;
//CHAPTER12MOD
case TENANTTYPE_LINKEDFILE:
hr=OleCreateLinkToFile((LPSTR)pvType, IID_IUnknown
, OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
break;
case TENANTTYPE_LINKEDOBJECTFROMDATA:
hr=OleCreateLinkFromData((LPDATAOBJECT)pvType, IID_IUnknown
, OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
break;
//End CHAPTER12MOD
default:
break;
}
//If creation didn't work, get rid for the element FOpen created.
if (FAILED(hr))
{
Destroy(pIStorage);
return UCREATE_FAILED;
}
//We don't get the size if PatronObject data was seen already.
FObjectInitialize(pObj, pFE, dwData);
//We depend here on m_pIOleObject having been initialized.
if ((0==pszl->cx && 0==pszl->cy))
{
SIZEL szl;
//Try to get the real size of the object, default to 2"*2"
SETSIZEL((*pszl), 2*LOMETRIC_PER_INCH, 2*LOMETRIC_PER_INCH);